using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Documents;

namespace ResourceBlender_Express
{
    /// <summary>
    /// Miscellaneous WPF utility methods
    /// </summary>
	public class WPFUtils {
        /// <summary>
        /// Gets whether the command assigned to an ICommandSource can execute.
        /// </summary>
        /// <param name="commandSource">The command to verify</param>
        /// <returns><c>true</c> if the command can execute, otherwise false</returns>
        public static bool CanExecuteCommandSource(ICommandSource commandSource) {
            ICommand baseCommand = commandSource.Command;
            if(baseCommand == null) {
                return false;
            }
            object commandParameter = commandSource.CommandParameter;
            IInputElement commandTarget = commandSource.CommandTarget;
            RoutedCommand command = baseCommand as RoutedCommand;
            if(command == null) {
                return baseCommand.CanExecute(commandParameter);
            } else if(commandTarget == null) {
                commandTarget = commandSource as IInputElement;
            }
            return command.CanExecute(commandParameter, commandTarget);
        }

        /// <summary>
        /// Navigates the visual tree upwards from an to it's parent of the given type.
        /// </summary>
        /// <param name="dependencyObject">The element whose parent to find.</param>
        /// <param name="ancestorType">The type of the parent to find.</param>
        /// <returns>The parent element of the specified type, or null if there is no parent.</returns>
        public static DependencyObject GetParentOfType(DependencyObject dependencyObject, Type ancestorType) {
            if(dependencyObject == null) {
                return null;
            } else if(dependencyObject.GetType() == ancestorType) {
                return dependencyObject;
            } else {
                return GetParentOfType(VisualTreeHelper.GetParent(dependencyObject), ancestorType);
            }
        }

        /// <summary>
        /// Generates a Table which can be added to a FlowDocument.
        /// </summary>
        /// <param name="items">The items to add to the table. Each KeyValuePair is one row</param>
        /// <returns>A Table containing the specified items as rows</returns>
        public static Table GenerateFlowTable(ICollection<KeyValuePair<string, string>> items) {
            Table tbl = new Table();
            tbl.Columns.Add(new TableColumn());
            tbl.Columns.Add(new TableColumn());
            tbl.CellSpacing = 0;
            if(items.Count > 0) {
                TableRowGroup rows = new TableRowGroup();
                tbl.RowGroups.Add(rows);
                foreach(KeyValuePair<string, string> itemRow in items) {
                    TableRow row = new TableRow();
                    TableCell leftCell = new TableCell(new Paragraph(new Run(itemRow.Key))),
                              rightCell = new TableCell(new Paragraph(new Run(itemRow.Value)));
                    row.Cells.Add(leftCell);
                    row.Cells.Add(rightCell);
                    rows.Rows.Add(row);
                }
                rows.Rows[0].FontWeight = FontWeights.Bold;
                rows.Rows[0].Cells[0].TextAlignment = TextAlignment.Center;
                rows.Rows[0].Cells[1].TextAlignment = TextAlignment.Center;
            }
            return tbl;
        }
	}
}
